#!/usr/local/bin/perl

#	VPR routing file interpreter by Jisoon Kim. 
#	July 30, 2007
#	Reads in .r file outputted from VPR and saves all
# connection information into a 2D array. Each array block
# represents a block in the FPGA. A Switch box connects
# a CLB or a Pad to a track. A Connection box connects
# a track to a track. The coordinate of this array
# does not correlate with the VPR's coordinate system.
# (0, 0) represents the lower left corner of the FPGA
# NOT including the pads. And then each half step in VPR
# is a full step in here.
#
#	This program written to convert VPR's netlist into
# a SPECTRE format netlist. Currently, this program only
# reads in the .r file and saves information to a database.
# IT DOES NOT PRODUCE A SPECTRE NETLIST.

#FILE NAME
open( ROUTE, "i.r") or die "Doesn't exist";

$line = <ROUTE>;
$line =~ /(\d)/;
$size = $1 * 2 + 1;
@grid;

@prevR = ("NOT", "NOT");

for $line (<ROUTE>){
	$line =~ /((\w+) ((\()(\d),(\d)(\)))  (\w+:) (\d))/;

	$name = $2;
	$posx = $5;
	$posy = $6;
	$posxend = -1;
	$posyend = -1;
	$origin = $8;
	$originNum = $9;
	$origin =~ s/://;
		
	if( $name eq "to"){
		$line =~/((\w+) ((\()(\d),(\d)(\))) to ((\()(\d),(\d)(\)))  (\w+:) (\d))/;
		$name = $2;
		$posx = $5;
		$posy = $6;
		$posxend = $10;
		$posyend = $11;
		$origin = $13;
		$originNum = $14;
		$origin =~ s/://;
		
		if( $name eq "CHANX") {
			$y = $posy *2;
			if( $posx > $posxend){
				$k = $posx-1;
				$end = $posxend;
			}else{
				$k = $posxend-1;
				$end = $posx;
			}
			for( $k ; $k>= $end; $k--){
				$grid[$k*2][$y]{Type} = "Connection";
				$grid[$k*2][$y]{Connections} = $grid[$k*2][$y]{Connections}." "."W".$origin.$originNum."to"."E".$origin.$originNum;
			}
		}
		elsif( $name eq "CHANY") {
			$x = $posx *2;
			if( $posy > $posyend){
				$k = $posy-1;
				$end = $posyend;
			}else{
				$k = $posyend-1;
				$end = $posy;
			}
			for( $k ; $k>= $end; $k--){
				$grid[$x][$k*2]{Type} = "Connection";
				$grid[$x][$k*2]{Connections} = $grid[$x][$k*2]{Connections}." "."N".$origin.$originNum."to"."S".$origin.$originNum;
			}
		}
	}
	@R = ( $name, $posx, $posy, $origin, $originNum);

	#SAVES INTO ARRAY
	if (!($name eq "SOURCE") && $prevR[0] eq "NOT" ){
		@prevR = @R;
		print "first \n";
	}
	elsif ( $prevR[0] eq "OPIN"||$prevR[0] eq "IPIN" && !($name eq "OPIN"||$name eq "IPIN"||$name eq "SINK" )){
		if($name eq "CHANY"){
			$x = $posx * 2;
			$y = ($posy * 2) - 1;
			
		}
		elsif($name eq "CHANX"){
			$x = ($posx * 2) - 1;
			$y = $posy *2;
		}
		
		$grid[$x][$y]{Type} = "Switch";
		$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." ".$prevR[3].$prevR[4]."to".$origin.$originNum;
		
		print $posx.",".$posy." ".$prevR[1].",".$prevR[2]." ".$prevR[3],$prevR[4],"to",$origin,$originNum." ";
		print $x.",".$y." ".$prevR[0].$prevR[4]." 1".$name.$originNum."\n";
	
		if($posxend != -1 && $posyend != -1){
			$R[1]=$posxend;
			$R[2]=$posyend;
		}
		@prevR = @R;
	}
	elsif ( $name eq "OPIN"||$name eq "IPIN" && !($prevR[0] eq "OPIN"||$prevR[0] eq "IPIN"||$name eq "SINK" )){
		if($prevR[0] eq "CHANY"){
			$x = $prevR[1] * 2;
			$y = ($prevR[2] * 2) - 1;
			
		}
		elsif($prevR[0] eq "CHANX"){
			$x = ($prevR[1]* 2) - 1;
			$y = $prevR[2]*2;
		}
		print $posx.",".$posy." ".$prevR[1].",".$prevR[2]." ".$prevR[3],$prevR[4],"to",$origin,$originNum." ";
		$grid[$x][$y]{Type} = "Switch";
		$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." ".$origin.$originNum."to".$prevR[3].$prevR[4];
		print $x.",".$y." ".$prevR[0].$prevR[4]." 2".$name.$originNum."\n";
		if($posxend != -1 && $posyend != -1){
			$R[1]=$posxend;
			$R[2]=$posyend;
		}
		@prevR = @R;
	}
	elsif ( $name eq "CHANX" && $prevR[0] eq "CHANY" || $name eq "CHANY" && $prevR[0] eq "CHANX"){
		
		if( $prevR[1]==$posx && $prevR[2]==$posy && $prevR[0] eq "CHANY"){
			$x = $prevR[1] * 2;
			$y = $prevR[2] * 2;
			$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." "."S".$prevR[3].$prevR[4]."to"."W".$origin.$originNum;
						print "SW ". $grid[$x][$y]{Connections} ."\n";
		}
		elsif( $prevR[1]==$posx && $prevR[2]==$posy && $prevR[0] eq "CHANX"){
			$x = $prevR[1] * 2;
			$y = $prevR[2] * 2;
			$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." "."W".$prevR[3].$prevR[4]."to"."S".$origin.$originNum;

		}
		elsif( $prevR[1]<$posx && $prevR[2] == $posy && $prevR[0] eq "CHANY"){
			$x = $prevR[1] * 2;
			$y = $prevR[2] * 2;
			$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." "."S".$prevR[3].$prevR[4]."to"."E".$origin.$originNum;
		}
		elsif( $prevR[1]>$posx && $prevR[2] == $posy && $prevR[0] eq "CHANX"){
			$x = $posx * 2;
			$y = $posy * 2;
			$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." "."E".$prevR[3].$prevR[4]."to"."S".$origin.$originNum;
		}
		elsif( $prevR[2]<$posy && $prevR[1]==$posx && $prevR[0] eq "CHANY"){
			$x = $prevR[1] * 2;
			$y = $prevR[2] * 2;
			$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." "."S".$prevR[3].$prevR[4]."to"."N".$origin.$originNum;
		}
		elsif( $prevR[2]>$posy && $prevR[1]==$posx && $prevR[0] eq "CHANY"){
			$x = $posx * 2;
			$y = $posy * 2;
			$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." "."N".$prevR[3].$prevR[4]."to"."S".$origin.$originNum;
		}
		elsif( $prevR[1]<$posx && $prevR[2]==$posy && $prevR[0] eq "CHANX"){
			$x = $prevR[1] * 2;
			$y = $prevR[2] * 2;
			$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." "."W".$prevR[3].$prevR[4]."to"."E".$origin.$originNum;
						
		}
		elsif( $prevR[1]>$posx && $prevR[2]==$posy && $prevR[0] eq "CHANX"){
			$x = $posx * 2;
			$y = $posy * 2;
			$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." "."E".$prevR[3].$prevR[4]."to"."W".$origin.$originNum;
		}
		elsif( $prevR[2]<$posy && $prevR[1] == $posx && $prevR[0] eq "CHANX"){
			$x = $prevR[1] * 2;
			$y = $prevR[2] * 2;
			$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." "."W".$prevR[3].$prevR[4]."to"."N".$origin.$originNum;
		}
		elsif( $prevR[2]>$posy && $prevR[1] == $posx && $prevR[0] eq "CHANY"){
			$x = $posx * 2;
			$y = $posy * 2;
			$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." "."N".$prevR[3].$prevR[4]."to"."W".$origin.$originNum;
		}
		elsif( $prevR[2]<$posy && $prevR[1]>$posx ){
			$x = ($prevR[1]-1)*2;
			$y = $prevR[2]*2;
			$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." "."E".$prevR[3].$prevR[4]."to"."N".$origin.$originNum;
		}
		elsif( $prevR[2]>$posy && $prevR[1]<$posx ){
			$x = ($posx-1)*2;
			$y = $posy*2;
			$grid[$x][$y]{Connections} = $grid[$x][$y]{Connections}." "."N".$prevR[3].$prevR[4]."to"."E".$origin.$originNum;
		}
		$grid[$x][$y]{Type} = "Connection";

		print $posx.",".$posy." ".$prevR[1].",".$prevR[2]." ".$prevR[3],$prevR[4],"to",$origin,$originNum." ";
		print $x.",".$y." ".$prevR[0].$prevR[4]." 3".$name.$originNum."\n";

		if($posxend != -1 && $posyend != -1){
			$R[1]=$posxend;
			$R[2]=$posyend;
		}
		@prevR = @R;
	}
	elsif ($name eq "SINK" || $prevR[0] eq ""){
		@prevR = ("NOT");
		print "NOT\n";


	}
	for($j = 0; $j < 5; $j++){
		print "[".$R[$j] . "], ";
	}
	print "\n $prevR[0]\n";

}
for($k = $size-1 ; $k>=0 ; $k--){
	for($j = 0; $j < $size; $j++){
		print "[".$grid[$j][$k]{Connections} . "], ";
	}
	print "\n";
}
